//#include "stdafx.h"
#include "mylist.h"



MyNode::MyNode()
{
	pPrev = 0;
	pNext = 0;
	pData = 0;
	pList = 0;
}

MyList::MyList()
{
	pHead = 0;
	pTail = 0;
	dwSize = 0;
}

MyNode* MyList::push_back(void *pData)
{
	MyNode *pNode = new MyNode;
	pNode->pData = pData;
	pNode->pList = this;

	if(pTail ==  0)
	{
		//assert(pHead == 0);
		pHead = pTail = pNode;
	}
	else
	{
		pNode->pPrev = pTail;
		pTail->pNext = pNode;
		pTail = pNode;
	}

	dwSize++;

	return pNode;
}

MyNode* MyList::push_front(void *pData)
{
	MyNode *pNode = new MyNode;
	pNode->pData = pData;
	pNode->pList = this;

	if(pHead ==  0)
	{
		//assert(pTail == 0);
		pHead = pTail = pNode;
	}
	else
	{
		pNode->pNext = pHead;
		pHead->pPrev = pNode;
		pHead = pNode;
	}

	dwSize++;

	return pNode;
}

bool MyList::erase(MyNode *pNode)
{
	if(!pNode || pNode->pList != this)
		return false;
	if(dwSize == 0)
	{
		//assert(dwSize != 0);
		return false;
	}

	MyNode* pPrev = pNode->pPrev;
	MyNode* pNext = pNode->pNext;

	if(pPrev)
		pPrev->pNext = pNext;
	if(pNext)
		pNext->pPrev = pPrev;

	if(pNode == pTail)
		pTail =  pPrev;
	if(pNode == pHead)
		pHead =  pNext;

	delete pNode;
	//delete pData;

	dwSize--;

	return true;
}

bool MyList::cut(MyNode *pNode)
{
	if(!pNode || pNode->pList != this)
		return false;
	if(dwSize == 0)
	{
		//assert(dwSize != 0);
		return false;
	}

	MyNode* pPrev = pNode->pPrev;
	MyNode* pNext = pNode->pNext;

	if(pPrev)
		pPrev->pNext = pNext;
	if(pNext)
		pNext->pPrev = pPrev;

	if(pNode == pTail)
		pTail =  pPrev;
	if(pNode == pHead)
		pHead =  pNext;

	pNode->pList = 0;
	dwSize--;

	return true;
}

bool MyList::splice_back(MyNode *pNode)
{
	if(!pNode || pNode->pList != 0)
		return false;

	pNode->pList = this;

	if(pTail ==  0)
	{
		//assert(pHead == 0);
		pHead = pTail = pNode;
		pNode->pPrev = pNode->pNext = 0;
	}
	else
	{
		pNode->pNext = 0;
		pNode->pPrev = pTail;
		pTail->pNext = pNode;
		pTail = pNode;
	}

	dwSize++;

	return true;
}

bool MyList::splice_front(MyNode *pNode)
{
	if(!pNode || pNode->pList != 0)
		return false;

	pNode->pList = this;

	if(pHead ==  0)
	{
		//assert(pTail == 0);
		pHead = pTail = pNode;
		pNode->pPrev = pNode->pNext = 0;
	}
	else
	{
		pNode->pPrev = 0;
		pNode->pNext = pHead;
		pHead->pPrev = pNode;
		pHead = pNode;
	}

	dwSize++;

	return true;
}

void* MyList::pop_back()
{
	MyNode* pNode = pTail;
	void* pData = 0;
	if(cut(pNode))
	{
		pData = pNode->pData;
		delete pNode;
	}

	return pData;
}

void* MyList::pop_front()
{
	MyNode* pNode = pHead;
	void* pData = 0;
	if(cut(pNode))
	{
		pData = pNode->pData;
		delete pNode;
	}

	return pData;
}


void MyList::clear(bool bDelData)
{	
	while(pHead)
	{
		if(bDelData )
		{
			delete pHead->pData;
		}
		erase(pHead);
	}
	dwSize = 0;
}